#include "trafficcontrol.h"
#include "world.h"
#include <QDebug>

//-----------------------------------------------------------------------------
// TrafficControl::Connection
//-----------------------------------------------------------------------------
TrafficControl::Connection::Connection(
  const StreetMap::Road *from, const unsigned int fromLane,
  const StreetMap::Road *to, const unsigned int toLane)
{
  this->from = from;
  this->to = to;
  this->fromLane = fromLane;
  this->toLane= toLane;
}

//-----------------------------------------------------------------------------
// TrafficControl::State
//-----------------------------------------------------------------------------
TrafficControl::State::State(const QString &name)
{
  mName = name;
  mConnections.clear();
  mGreenTime = 0.0;
  mYellowTime = 0.0;
  mPostRedTime = 0.0;
}

TrafficControl::State::~State()
{
  //foreach(Connection *c, mConnections)
  //  delete c;
  mConnections.clear();
}

void TrafficControl::State::setName(const QString &name)
{
  mName = name;
}

QString TrafficControl::State::name() const
{
  return mName;
}

TrafficControl::ConnectionList TrafficControl::State::getConnections()
{
  return mConnections;
}

void TrafficControl::State::setGreenTime(const qreal timeInSeconds)
{
  mGreenTime = timeInSeconds;
}

qreal TrafficControl::State::greenTime() const
{
  return mGreenTime;
}

void TrafficControl::State::setYellowTime(const qreal timeInSeconds)
{
  mYellowTime = timeInSeconds;
}

qreal TrafficControl::State::yellowTime() const
{
  return mYellowTime;
}

void TrafficControl::State::setPostRedTime(const qreal timeInSeconds)
{
  mPostRedTime = timeInSeconds;
}

qreal TrafficControl::State::postRedTime() const
{
  return mPostRedTime;
}

void TrafficControl::State::setLightColor(const TrafficControl::LIGHT_COLOR color)
{
  mCurrentColor = color;
}

TrafficControl::LIGHT_COLOR TrafficControl::State::lightColor() const
{
  return mCurrentColor;
}

TrafficControl::LIGHT_COLOR TrafficControl::State::lightColor(
    const StreetMap::Road *from, const unsigned int fromLane,
    const StreetMap::Road *to, const unsigned int toLane) const
{
  for (int i=0; i<mConnections.size(); i++)
  {
    const TrafficControl::Connection *c = mConnections.at(i);

    if (c && c->from == from && c->fromLane == fromLane && c->to == to && c->toLane == toLane)
    {
      return mCurrentColor;
    }
  }
  return LIGHT_RED;
}

void TrafficControl::State::addConnection(Connection *connection)
{
  mConnections.push_back(connection);
}

bool TrafficControl::State::operator==(const State &other) const
{
  if (name() == other.name())
    return true;
  else
    return false;
}

//-----------------------------------------------------------------------------
// TrafficControl
//-----------------------------------------------------------------------------
TrafficControl::TrafficControl()
{
  mIntersection = NULL;
  mStates.clear();
  mType = TYPE_NONE;
  mCurrentStateIndex = 0;
  mTimeSinceStateChange = 0.0;
}

TrafficControl::~TrafficControl()
{
  //foreach(State *s, mStates)
  //  delete s;
  mStates.clear();
}

void TrafficControl::setIntersection(const StreetMap::Intersection *intersection)
{
  mIntersection = intersection;
}

const StreetMap::Intersection* TrafficControl::intersection() const
{
  return mIntersection;
}

void TrafficControl::addState(TrafficControl::State *state)
{
  if (state)
  {
    foreach (TrafficControl::State *s, mStates)
    {
      if (s && s->name() == state->name())
      {
        qDebug() << "TrafficControl ERROR: A state named" << state->name() << "already exists for this control!";
        return;
      }
    }
    //qDebug() << "TrafficControl: Adding state" << state->name();
    mStates.push_back(state);
  }
}

//TrafficControl::State TrafficControl::getState(const QString &name) const
//{
//  return mStates[name];
//}

TrafficControl::State* TrafficControl::currentState() const
{
  return mStates.at(mCurrentStateIndex);
}

void TrafficControl::setType(const TrafficControl::CONTROL_TYPE type)
{
  mType = type;
}

TrafficControl::CONTROL_TYPE TrafficControl::type() const
{
  return mType;
}

void TrafficControl::tick()
{
  if (mType == TYPE_LIGHT)
  {
    mTimeSinceStateChange += World::gSimTimeStep;
    State *curr = currentState();
    //qDebug() << "TC:" << curr->name() << "state=" << mCurrentStateIndex;

    if (mTimeSinceStateChange > curr->greenTime())
    {
      if (mTimeSinceStateChange > (curr->greenTime() + curr->yellowTime()))
      {
        curr->setLightColor(LIGHT_RED);
        //qDebug() << "TC:" << curr->name() << "state=" << mCurrentStateIndex << "color=RED";
        if (mTimeSinceStateChange > (curr->greenTime() + curr->yellowTime()+ curr->postRedTime()))
        {
          // Change to next state
          mTimeSinceStateChange = 0.0;
          mCurrentStateIndex++;
          if (mCurrentStateIndex >= mStates.size())
            mCurrentStateIndex = 0;
        }
      }
      else
      {
        curr->setLightColor(LIGHT_YELLOW);
        //qDebug() << "TC:" << curr->name() << "state=" << mCurrentStateIndex << "color=YELLOW";
      }
    }
    else
    {
      curr->setLightColor(LIGHT_GREEN);
      //qDebug() << "TC:" << curr->name() << "state=" << mCurrentStateIndex << "color=GREEN";
    }
  }
}


